import pygame
import sys
import time
from pygame.locals import *

# 初始化 Pygame
pygame.init()

# 屏幕尺寸与棋盘设置
SCREEN_WIDTH, SCREEN_HEIGHT = 595, 719
GRID_SIZE = 62
ORIGIN_X, ORIGIN_Y = 24, 21
Winner = 0
Round = 0
level = 0
rear = 0
King_red = (5 , 10)
King_black = (5 , 1)
From = [(0,0)] * 100
To = [(0,0)] * 100
Eat = [0] * 100
red_board = [[0] * 11 for _ in range(10)]
black_board = [[0] * 11 for _ in range(10)]

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("象棋")

# 加载图片
chessboard = pygame.image.load("棋盘.jpg")
background = pygame.image.load("初始界面.jpg")
kaishi = pygame.image.load("开始.png")
huiqi = pygame.image.load("悔棋.png")
qiuhe = pygame.image.load("求和.png")
renshu = pygame.image.load("认输.png")
ask_huiqi = pygame.image.load("悔棋请求.png")
ask_qiuhe = pygame.image.load("和棋请求.png")
fupan = pygame.image.load("复盘.png")
caidan = pygame.image.load("菜单.png")
shang = pygame.image.load("上一步.png")
xia = pygame.image.load("下一步.png")
Jiangjun = pygame.image.load("jiangjun.png")
Juesha = pygame.image.load("juesha.png")
Chi = pygame.image.load("Chi.png")
red_pieces = {
    1: pygame.image.load("red1.png"),
    2: pygame.image.load("red2.png"),
    3: pygame.image.load("red3.png"),
    4: pygame.image.load("red4.png"),
    5: pygame.image.load("red5.png"),
    6: pygame.image.load("red6.png"),
    7: pygame.image.load("red7.png"),
}
lred_pieces = {
    1: pygame.image.load("lred1.png"),
    2: pygame.image.load("lred2.png"),
    3: pygame.image.load("lred3.png"),
    4: pygame.image.load("lred4.png"),
    5: pygame.image.load("lred5.png"),
    6: pygame.image.load("lred6.png"),
    7: pygame.image.load("lred7.png"),
}
black_pieces = {
    1: pygame.image.load("bla1.png"),
    2: pygame.image.load("bla2.png"),
    3: pygame.image.load("bla3.png"),
    4: pygame.image.load("bla4.png"),
    5: pygame.image.load("bla5.png"),
    6: pygame.image.load("bla6.png"),
    7: pygame.image.load("bla7.png"),
}
lblack_pieces = {
    1: pygame.image.load("lbla1.png"),
    2: pygame.image.load("lbla2.png"),
    3: pygame.image.load("lbla3.png"),
    4: pygame.image.load("lbla4.png"),
    5: pygame.image.load("lbla5.png"),
    6: pygame.image.load("lbla6.png"),
    7: pygame.image.load("lbla7.png"),
}


# 棋盘初始化
def init_board():

    global King_red, King_black

    # 红方布局
    King_red = (5 , 10)
    red_board[1][10], red_board[9][10] = 1, 1  # 车
    red_board[2][10], red_board[8][10] = 2, 2  # 马
    red_board[3][10], red_board[7][10] = 3, 3  # 象
    red_board[4][10], red_board[6][10] = 4, 4  # 士
    red_board[5][10] = 7  # 将
    red_board[1][7], red_board[3][7], red_board[5][7], red_board[7][7], red_board[9][7] = 6, 6, 6, 6, 6  # 卒
    red_board[2][8], red_board[8][8] = 5, 5  # 炮

    # 黑方布局
    King_black = (5 , 1)
    black_board[1][1], black_board[9][1] = 1, 1  # 车
    black_board[2][1], black_board[8][1] = 2, 2  # 马
    black_board[3][1], black_board[7][1] = 3, 3  # 象
    black_board[4][1], black_board[6][1] = 4, 4  # 士
    black_board[5][1] = 7  # 将
    black_board[1][4], black_board[3][4], black_board[5][4], black_board[7][4], black_board[9][4] = 6, 6, 6, 6, 6  # 卒
    black_board[2][3], black_board[8][3] = 5, 5  # 炮

# 渲染棋盘与棋子
def draw_board():
    global level
    screen.blit(background, (0, 0))
    screen.blit(chessboard, (0, 0))

    # 绘制红方棋子
    for x in range(10):
        for y in range(11):
            piece = red_board[x][y]
            if piece:
                screen.blit(red_pieces[piece], (ORIGIN_X + GRID_SIZE * (x - 1), ORIGIN_Y + GRID_SIZE * (y - 1)))

    # 绘制黑方棋子
    for x in range(10):
        for y in range(11):
            piece = black_board[x][y]
            if piece:
                screen.blit(black_pieces[piece], (ORIGIN_X + GRID_SIZE * (x - 1), ORIGIN_Y + GRID_SIZE * (y - 1)))
    if level == 1 :
        screen.blit(huiqi, (47, 660))
        screen.blit(renshu, (242, 660))
        screen.blit(qiuhe, (437, 660))
    if level == 2 :
        screen.blit(fupan, (47, 660))
        screen.blit(caidan, (437, 660))
    if level == 3 :
        screen.blit(shang, (47, 660))
        screen.blit(xia, (242, 660))
        screen.blit(caidan, (437, 660))
        
# 获取棋盘位置
def get_board_position(mouse_x, mouse_y):
    x = (mouse_x - ORIGIN_X) // GRID_SIZE + 1
    y = (mouse_y - ORIGIN_Y) // GRID_SIZE + 1
    if 1 <= x <= 9 and 1 <= y <= 10:
        return x, y
    return None

def notepath(start, end, eat): #记录第rear步的操作，从哪走到哪，吃了什么棋子
    global rear, From, To, Eat
    rear += 1
    From[rear] = start 
    To[rear] = end
    Eat[rear] = eat

def Juesha_rendering():
    music_file = '绝杀.mp3'
    pygame.mixer.music.load(music_file)
    pygame.mixer.music.play()
    screen.blit(Juesha, (220, 270)) # 插入绝杀图片
    pygame.display.flip()
    time.sleep(2.5) # 延续绝杀提示时间

def Jiangjun_rendering():
    music_file = '将军.mp3'
    pygame.mixer.music.load(music_file)
    pygame.mixer.music.play()
    screen.blit(Jiangjun, (250, 270)) # 插入将军图片
    pygame.display.flip()
    time.sleep(1.5) # 延续将军提示时间

def Chi_rendering():
    music_file = '吃.mp3'
    pygame.mixer.music.load(music_file)
    pygame.mixer.music.play()
    screen.blit(Chi, (235, 270)) # 插入吃图片
    pygame.display.flip()
    time.sleep(1.5) # 延续吃提示时间

def request_qiuhe():
    screen.blit(ask_qiuhe, (150, 245))
    pygame.display.flip() # 显示图像
    Operation = 0
    while Operation == 0:
        for event in pygame.event.get():
            if event.type == QUIT: # 关闭
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1: # 点击鼠标左键
                x, y = event.pos
                if 310 < x < 425 and 370 < y < 410: # 点击同意
                    flag = True
                    Operation = 1
                    break
                if 170 < x < 285 and 370 < y < 3410: # 点击拒绝
                    flag = False
                    Operation = 1
                    break
    draw_board() # 渲染棋盘
    pygame.display.flip() # 显示图像
    return flag 
    
                
def request_huiqi():
    screen.blit(ask_huiqi, (150, 245))
    pygame.display.flip() # 显示图像
    Operation = 0
    while Operation == 0:
        for event in pygame.event.get():
            if event.type == QUIT: # 关闭
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1: # 点击鼠标左键
                x, y = event.pos
                if 310 < x < 425 and 370 < y < 410: # 点击同意
                    flag = True
                    Operation = 1
                    break
                if 170 < x < 285 and 370 < y < 3410: # 点击拒绝
                    flag = False
                    Operation = 1
                    break
    draw_board() # 渲染棋盘
    pygame.display.flip() # 显示图像
    return flag 

def backstep(): # 返回到上一步的局面
    global rear, From, To, Eat
    if rear == 0: # 没有上一步
        return
    bx, by = From[rear]
    newx, newy = To[rear]
    eat = Eat[rear]
    if rear % 2 == 1:  # rear是当前是奇数，则回溯的这一步是红方刚走棋子
        red_board[bx][by] = red_board[newx][newy]
        red_board[newx][newy] = 0
        black_board[newx][newy] = eat
        if red_board[bx][by] == 7: # 如果移动王，更新全局变量
            King_red = bx, by
    else:  # rear是当前是偶数，则回溯的这一步是黑方刚走棋子
        black_board[bx][by] = black_board[newx][newy]
        black_board[newx][newy] = 0
        red_board[newx][newy] = eat
        if black_board[bx][by] == 7:
            King_black = bx,by
    rear -= 1
    draw_board() # 渲染棋盘
    pygame.display.flip() # 显示图像

def nextstep(): # 进入下一步的局面
    global rear, From, To, Eat
    if From[rear+1] == (0,0) :
        return # 没有下一步
    rear += 1
    bx, by = From[rear]
    newx, newy = To[rear]
    eat = Eat[rear]
    if rear  % 2 == 1:  # rear是当前是奇数，则进行的这一步是红方走棋子
        red_board[newx][newy] = red_board[bx][by]
        red_board[bx][by] = 0
        black_board[newx][newy] = 0
        if red_board[newx][newy] == 7: # 如果移动王，更新全局变量
            King_red = newx, newy
    else:  # rear是当前是偶数，则进行的这一步是黑方刚走棋子
        black_board[newx][newy] = black_board[bx][by]
        black_board[bx][by] = 0
        red_board[newx][newy] = 0
        if black_board[newx][newy] == 7:
            King_black = newx,newy
    draw_board() # 渲染棋盘
    pygame.display.flip() # 显示图像

def check_black(piece, start, end): # 种类为piece的黑旗根据象棋规则能否从start移动到end
    global Round, King_red, King_black
    bx, by = start
    newx, newy = end
    if start == end : # 原地不动可行
        return True
    if black_board[newx][newy]: # 不能走到己方棋子上
        return False
 
    if piece == 1:  # 车
        if (bx-newx)*(by-newy) != 0:
            return False # 车只能走同行或同列
        num = 0
        if by == newy:
            for x in range(min(bx, newx) + 1, max(bx, newx)):
                if black_board[x][by] or red_board[x][by]:
                    num += 1
        if bx == newx:
            for y in range(min(by, newy) + 1, max(by, newy)):
                if black_board[bx][y] or red_board[bx][y]:
                    num += 1
        return True if num == 0 else False
        
    elif piece == 2:  # 马
        dx = newx - bx
        dy = newy - by
        if abs(dx * dy) != 2:  # 不符合马走日规则
            return False
        if abs(dx) == 2:
            x = (newx + bx) // 2
            y = by
        elif abs(dy) == 2:
            y = (newy + by) // 2
            x = bx
        if red_board[x][y] or black_board[x][y]:  # 马脚被阻挡
            return False
        return True
    
    elif piece == 3:  # 象
        dx = newx - bx
        dy = newy - by
        if newy >= 6: 
            return False
        if abs(dx) != 2 or abs(dy) != 2:  # 必须斜着走两格
            return False
        x = (newx + bx) // 2
        y = (newy + by) // 2  # 计算象脚的坐标
        if red_board[x][y] or black_board[x][y]:  # 象脚被阻挡
            return False
        return True
    
    elif piece == 4:  # 士
        dx = newx - bx
        dy = newy - by
        # 士只能在九宫内且只能走“口”字形
        if 4 <= newx <= 6 and 1 <= newy <= 3 and abs(dx * dy) == 1:
            return True
        return False
    
    elif piece == 5:  # 炮
        if (bx-newx)*(by-newy) != 0:
            return False # 炮只能走同行或同列
        num = 0
        if by == newy:
            for x in range(min(bx, newx) + 1, max(bx, newx)):
                if black_board[x][by] or red_board[x][by]:
                    num += 1
        if bx == newx:
            for y in range(min(by, newy) + 1, max(by, newy)):
                if black_board[bx][y] or red_board[bx][y]:
                    num += 1
        if num==0 and red_board[newx][newy] == 0:
            return True
        if num==1 and red_board[newx][newy]:
            return True
        return False
    
    elif piece == 6:  # 卒/兵
        dx = newx - bx
        dy = newy - by
        if abs(dx + dy) != 1 or dx * dy != 0:  # 兵只能直着走，且只能走一格
            return False
        if by < 6 and dy <= 0:  # 未过楚河汉界兵只能往前走
            return False
        if by >= 6 and dy == -1:  # 过了楚河汉界兵不能往回走
            return False
        return True
    
    elif piece == 7:  # 将/帅
        dx = newx - bx
        dy = newy - by
        # 将只能在九宫内且只能直着走，且只能走一格
        if 4 <= newx <= 6 and 1 <= newy <= 3 and abs(dx + dy) == 1 and dx * dy == 0:
            return True
        return False
    
def check_red(piece, start, end): # 种类为piece的红旗根据象棋规则能否从start移动到end
    global Round, King_red, King_black
    bx, by = start
    newx, newy = end
    if start == end :
        return True
    if red_board[newx][newy]:
        return False
 
    if piece == 1:  # 车
        if (bx-newx)*(by-newy) != 0:
            return False # 车只能走同行或同列
        num = 0
        if by == newy:
            for x in range(min(bx, newx) + 1, max(bx, newx)):
                if black_board[x][by] or red_board[x][by]:
                    num += 1
        if bx == newx:
            for y in range(min(by, newy) + 1, max(by, newy)):
                if black_board[bx][y] or red_board[bx][y]:
                    num += 1
        return True if num == 0 else False
        
    elif piece == 2:  # 马
        dx = newx - bx
        dy = newy - by
        if abs(dx * dy) != 2:  # 不符合马走日规则
            return False
        if abs(dx) == 2:
            x = (newx + bx) // 2
            y = by
        elif abs(dy) == 2:
            y = (newy + by) // 2
            x = bx
        if red_board[x][y] or black_board[x][y]:  # 马脚被阻挡
            return False
        return True
    
    elif piece == 3:  # 象
        dx = newx - bx
        dy = newy - by
        if newy <= 5 :
            return False
        if abs(dx) != 2 or abs(dy) != 2:  # 必须斜着走两格
            return False
        x = (newx + bx) // 2
        y = (newy + by) // 2  # 计算象脚的坐标
        if red_board[x][y] or black_board[x][y]:  # 象脚被阻挡
            return False
        return True
    
    elif piece == 4:  # 士
        dx = newx - bx
        dy = newy - by
        # 士只能在九宫内且只能走“口”字形
        if 4 <= newx <= 6 and 8 <= newy <= 10 and abs(dx * dy) == 1:
            return True
        return False
    
    elif piece == 5:  # 炮
        if (bx-newx)*(by-newy) != 0:
            return False # 炮只能走同行或同列
        num = 0
        if by == newy:
            for x in range(min(bx, newx) + 1, max(bx, newx)):
                if black_board[x][by] or red_board[x][by]:
                    num += 1
        if bx == newx:
            for y in range(min(by, newy) + 1, max(by, newy)):
                if black_board[bx][y] or red_board[bx][y]:
                    num += 1
        if num==0 and black_board[newx][newy] == 0:
            return True
        if num==1 and black_board[newx][newy]:
            return True
        return False
    
    elif piece == 6:  # 卒/兵
        dx = newx - bx
        dy = newy - by
        if abs(dx + dy) != 1 or dx * dy != 0:  # 兵只能直着走，且只能走一格
            return False
        if by > 5 and dy >= 0:  # 未过楚河汉界兵只能往前走
            return False
        if by <= 5 and dy == 1:  # 过了楚河汉界兵不能往回走
            return False
        return True
    
    elif piece == 7:  # 将/帅
        dx = newx - bx
        dy = newy - by
        if red_board[newx][newy]:  # 目标点位是己方棋子不可行
            return False
        # 将只能在九宫内且只能直着走，且只能走一格
        if 4 <= newx <= 6 and 8 <= newy <= 10 and abs(dx + dy) == 1 and dx * dy == 0:
            return True
        return False

def threat_to_black(): # 判断当前局面是否能对黑方的将造成将军
    global King_red, King_black
    for x in range(1, 10):  
        for y in range(1, 11): 
            if red_board[x][y]: # 枚举棋盘上所有的红棋
                piece = red_board[x][y]
                if piece == 7: # 判断王不对王的局面，把将帅的行走规则看成车
                    if check_red(1, (x, y), King_black): # 将面对帅，则视为将军
                        return True
                if piece != 7:
                    if check_red(piece, (x, y), King_black): # 该棋子能吃到将，视为将军
                        return True
    return False  # 没有将军

def threat_to_red(): # 判断当前局面是否能对红方的帅造成将军
    global King_red, King_black
    for x in range(1, 10):  
        for y in range(1, 11): 
            if black_board[x][y]: # 枚举棋盘上所有的黑棋
                piece = black_board[x][y]
                if piece == 7: # 判断王不对王的局面，把将帅的行走规则看成车
                    if check_black(1, (x, y), King_red): # 将面对帅，则视为将军
                        return True
                if piece != 7:
                    if check_black(piece, (x, y), King_red): # 该棋子能吃到帅，视为将军
                        return True
    return False  # 没有将军

def assume_black(piece, start, end):
    global King_red, King_black
    bx, by = start
    newx,newy = end
    eat = red_board[newx][newy] # 先记录有没有吃掉对方棋子
    red_board[newx][newy] = 0
    black_board[newx][newy] = piece # 棋子移动至end位置
    black_board[bx][by] = 0 # start位置没有棋子了
    if piece == 7 :
        King_black = end # 移动的是王，暂时更新全局变量
    flag = threat_to_black() # 黑方走一步之后是否被将军
    #变回原来的局面
    if piece == 7 :
        King_black = start 
    red_board[newx][newy] = eat
    black_board[bx][by] = piece
    black_board[newx][newy] =0
    return flag

def assume_red(piece, start, end): # 假定了棋子从start移动到end的局面
    global King_red,King_black
    bx, by = start
    newx,newy = end
    eat = black_board[newx][newy] # 先记录有没有吃掉对方棋子
    black_board[newx][newy] = 0
    red_board[newx][newy] = piece # 棋子移动至end位置
    red_board[bx][by] = 0 # start位置没有棋子了
    if piece == 7 :
        King_red = end # 移动的是王，暂时更新全局变量
    flag = threat_to_red() # 红方走一步之后是否被将军
    #变回原来的局面
    if piece == 7 :
        King_red = start 
    black_board[newx][newy] = eat
    red_board[bx][by] = piece
    red_board[newx][newy] =0
    return flag

def Juesha_black_check(): # 判断当前局面黑方是否被绝杀
    global Round, King_red, King_black 
    for x in range(1, 10):
        for y in range(1, 11):
            if black_board[x][y]: # 枚举所有黑棋
                 piece = black_board[x][y] # 选中该枚棋子
                 for newx in range(1, 10):
                    for newy in range(1, 11): # 枚举棋盘所有点位
                        if x == newx and y == newy: 
                            continue
                        if check_black(piece, (x, y), (newx, newy)): # 枚举该棋子下一步所有可落的点位
                            if not assume_black(piece, (x,y), (newx,newy)) :
                                return False   # 只要有一种方案走完不会被将军，则不是绝杀
    return True

def Juesha_red_check(): # 判断当前局面红方是否被绝杀
    global Round, King_red, King_black
    for x in range(1, 10):
        for y in range(1, 11):
            if red_board[x][y]: # 枚举所有红棋
                 piece = red_board[x][y] # 选中该枚棋子
                 for newx in range(1, 10):
                    for newy in range(1, 11): # 枚举棋盘所有点位
                        if x == newx and y == newy: 
                            continue
                        if check_red(piece, (x, y), (newx, newy)): # 枚举该棋子下一步所有可落的点位
                            if not assume_red(piece, (x,y), (newx,newy)) :
                                return False   # 只要有一种方案走完不会被将军，则不是绝杀
    return True

def Move_black(piece, bx, by):
    global Round, King_red, King_black
    Operation = 0
    lastx ,lasty = bx, by
    screen.blit(lblack_pieces[piece], (ORIGIN_X + GRID_SIZE * (bx - 1), ORIGIN_Y + GRID_SIZE * (by - 1)))
    pygame.display.flip()
    while Operation == 0:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEMOTION:
                mouse_x, mouse_y = event.pos
                board_pos = get_board_position(mouse_x, mouse_y)
                if board_pos:
                    newx, newy = board_pos
                    if (newx, newy) == (lastx, lasty):
                        continue
                    if check_black(piece, (bx,by), (newx, newy)):
                        if assume_black(piece, (bx, by), (newx, newy)) and (bx, by) != (newx,newy):
                            continue
                        lastx, lasty = newx, newy
                        black_board[bx][by] = 0
                        draw_board()
                        screen.blit(lblack_pieces[piece], (ORIGIN_X + GRID_SIZE * (newx - 1), ORIGIN_Y + GRID_SIZE * (newy - 1)))
                        pygame.display.flip()
            if  event.type == MOUSEBUTTONDOWN and event.button == 1:
                Operation = 1
                break 
    if (lastx,lasty) != (bx,by) : 
        Round = 1
        notepath((bx,by), (lastx,lasty), red_board[lastx][lasty])
    if red_board[lastx][lasty] != 0: 
        red_board[lastx][lasty] = 0
    if (piece == 7): # 如果移动的是王，实时更新全局变量的信息
        King_black = (lastx, lasty)
    black_board[lastx][lasty] = piece

def Move_red(piece, bx, by):
    global Round, King_red, King_black # 全局变量声明
    Operation = 0 
    lastx ,lasty = bx, by # lastx ,lasty 表示上一次暗色棋子插入的坐标
    screen.blit(lred_pieces[piece], (ORIGIN_X + GRID_SIZE * (bx - 1), ORIGIN_Y + GRID_SIZE * (by - 1)))
    pygame.display.flip() # 将选中的棋子从棋盘中删除，并在该位置重新插入一个暗色棋子，清晰的表示当前选中了这枚棋子
    while Operation == 0:
        for event in pygame.event.get(): # 获取事件
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEMOTION: # 检测到鼠标移动
                mouse_x, mouse_y = event.pos
                board_pos = get_board_position(mouse_x, mouse_y)
                if board_pos: # 鼠标落在棋盘内
                    newx, newy = board_pos
                    if (newx, newy) == (lastx, lasty): # 避免重复刷新
                        continue
                    if check_red(piece, (bx,by), (newx, newy)): # 如果选中的棋子按照象棋规则能移动到鼠标当前的位置
                        if assume_red(piece, (bx, by), (newx, newy)) and (bx, by) != (newx,newy): # 并且移动之后不会被对方将军（原地不动可行）
                            continue
                        lastx, lasty = newx, newy
                        red_board[bx][by] = 0 # 重新画图时记得把选中的棋子暂时删掉
                        draw_board() # 在鼠标的位置插入一个暗色棋
                        screen.blit(lred_pieces[piece], (ORIGIN_X + GRID_SIZE * (newx - 1), ORIGIN_Y + GRID_SIZE * (newy - 1)))
                        pygame.display.flip()
            if event.type == MOUSEBUTTONDOWN and event.button == 1: 
                Operation = 1
                break # 检测到点击鼠标左键，则跳出循环
    if (lastx,lasty) !=(bx,by) : 
        Round = 1 # 棋子移动了，则操作成功， 等待交换棋权
        notepath((bx,by), (lastx,lasty), black_board[lastx][lasty]) # 记录此步操作
    if black_board[lastx][lasty] != 0: # 吃掉了对方棋子
        black_board[lastx][lasty] = 0
    if (piece == 7): # 如果移动的是王，实时更新全局变量的信息
        King_red = (lastx, lasty)
    red_board[lastx][lasty] = piece # 更新位置

def round_black():
    global Round, King_red, King_black, Winner, rear, Eat
    Operation = 0
    while Operation == 0:
        for event in pygame.event.get(): # 获取事件，这里主要获取鼠标信息
            if event.type == QUIT: # 关闭
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1:
                mouse_x, mouse_y = event.pos # 获取鼠标当前的坐标
                if rear>=2 and 47 < mouse_x < 152 and 660 < mouse_y <708 and request_huiqi(): # 点击悔棋，弹出悔棋请求窗口，并且对方同意
                    backstep()
                    backstep() # 悔棋就是倒退两步
                if 242 < mouse_x < 347 and 660 < mouse_y <708 : # 点击认输
                    Winner = 2
                    Operation = 1
                    break
                if 437 < mouse_x < 542 and 660 < mouse_y <708 and request_qiuhe(): # 点击求和，弹出和棋请求窗口，并且对方同意
                    Winner = 3
                    Operation = 1
                    break
                board_pos = get_board_position(mouse_x, mouse_y) # 将鼠标的坐标转化为棋盘坐标
                if board_pos: #若鼠标落在棋盘内
                    x,y = board_pos
                    if black_board[x][y] != 0: # 鼠标当前位置上有棋子
                        Move_black(black_board[x][y],x,y)
                        draw_board()
                        pygame.display.flip()
                        if Round == 0 : # 操作未成功
                            Operation = 1 
                            break
                        type = threat_to_red()
                        if type: # 判断当前局面是否造成将军
                            flag = Juesha_red_check() # 若将军则先判断当前局面是否为绝杀
                            if flag : 
                                Juesha_rendering() # 若绝杀，进入绝杀提示
                                Winner = 2
                            if not flag :
                                Jiangjun_rendering() # 将军提示
                        if not type:
                            if Eat[rear] : # 如果吃了对方棋子，进入吃子提示
                                Chi_rendering()
                            if not Eat[rear]: # 如果没吃，播放落子音效
                                music_file = '落子.mp3'
                                pygame.mixer.music.load(music_file)
                                pygame.mixer.music.play()
                        draw_board() # 重新绘制局面，使得提示消失
                        pygame.display.flip()
                        Operation = 1 
                        break
                    
def round_red():
    global Round, King_red, King_black, Winner, rear, Eat # 全局变量声明
    Operation = 0
    while Operation == 0:
        for event in pygame.event.get(): # 获取事件，这里主要获取鼠标信息
            if event.type == QUIT: # 关闭
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1: # 点击鼠标左键
                mouse_x, mouse_y = event.pos # 获取鼠标当前的坐标
                if rear >= 2 and 47 < mouse_x < 152 and 660 < mouse_y <708 and request_huiqi(): # 点击悔棋，弹出悔棋请求窗口，并且对方同意
                    backstep()
                    backstep() # 悔棋就是倒退两步
                if 242 < mouse_x < 347 and 660 < mouse_y <708 : # 点击认输
                    Winner = 2
                    Operation = 1
                    break
                if 437 < mouse_x < 542 and 660 < mouse_y <708 and request_qiuhe(): # 点击求和，弹出和棋请求窗口，并且对方同意
                    Winner = 3
                    Operation = 1
                    break
                board_pos = get_board_position(mouse_x, mouse_y) # 将鼠标的坐标转化为棋盘坐标
                if board_pos: #若鼠标落在棋盘内
                    x,y = board_pos 
                    if red_board[x][y] != 0: # 鼠标当前位置上有棋子
                        Move_red(red_board[x][y],x,y) # 如果当前鼠标位置有红棋，则模拟移动该棋子
                        draw_board() # 绘制新的局面
                        pygame.display.flip()
                        if Round == 0 : # 操作未成功
                            Operation = 1 
                            break
                        king_x, king_y = King_black
                        type = threat_to_black()
                        if type : # 判断当前局面是否造成将军
                            flag = Juesha_black_check() # 若将军则先判断当前局面是否为绝杀
                            if flag : 
                                Juesha_rendering() # 若绝杀，进入绝杀提示
                                Winner = 1
                            if not flag :
                                Jiangjun_rendering() # 将军提示
                        if not type:
                            if Eat[rear] : # 如果吃了对方棋子，进入吃子提示
                                Chi_rendering()
                            if not Eat[rear]: # 如果没吃，播放落子音效
                                music_file = '落子.mp3'
                                pygame.mixer.music.load(music_file)
                                pygame.mixer.music.play()
                        draw_board() # 重新绘制局面，使得提示消失
                        pygame.display.flip()
                        Operation = 1
                        break
def Menu():
    global level
    screen.blit(background, (0, 0))
    screen.blit(kaishi, (198, 408))
    pygame.display.flip()
    Operation = 0
    while Operation == 0 :
        for event in pygame.event.get():
            if event.type == QUIT: # 关闭
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1: # 点击鼠标左键
                x, y = event.pos
                if 198 < x < 398 and 408 < y < 508:
                    Operation = 1
                    level = 1  # 进入阶段 1
                    break

def Level3():
    draw_board() # 渲染棋盘
    pygame.display.flip() # 显示图像
    Operation = 0
    while Operation == 0 :
        for event in pygame.event.get():
            if event.type == QUIT: # 关闭
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1: # 点击鼠标左键
                x, y = event.pos
                if 437 < x < 542 and 660 < y <708: # 点击菜单，重新开始
                    pygame.quit()
                    sys.exit()
                if 47 < x < 152 and 660 < y <708: # 点击上一步
                    backstep()
                if 242 < x < 347 and 660 < y <708: # 点击下一步
                    nextstep()

def Level2():
    draw_board() # 渲染棋盘
    pygame.display.flip() # 显示图像
    Operation = 0
    while Operation == 0 :
        for event in pygame.event.get():
            if event.type == QUIT: # 关闭
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 1: # 点击鼠标左键
                x, y = event.pos
                if 437 < x < 542 and 660 < y <708: # 点击菜单，重新开始
                    pygame.quit()
                    sys.exit()
                if 47 < x < 152 and 660 < y <708: # 点击复盘，进入level3
                    Operation = 1
                    break 

def main():
    global Round , Winner, level
    Round = 0
    Winner = 0
    level = 0
    Menu() # 进入菜单
    init_board() # 棋盘布局
    clock = pygame.time.Clock() # 确保游戏运行流畅
    draw_board() # 渲染棋盘
    pygame.display.flip() # 显示图像
    turn = 0
    while Winner == 0:
        Round = 0
        if turn == 0: # 红方回合
            round_red()
        if turn == 1: # 黑方回合
            round_black()
        if Round == 1: # 操作成功，棋权转化
            turn=1-turn
    if Winner == 1 :
        print("红方胜利！")
    if Winner == 2 :
        print("黑方胜利！")
    if Winner == 3 :
        print("双方平局！")
    level += 1
    Level2()
    level += 1
    Level3()

if __name__ == "__main__":
    main()
